/**
 * 初始化：
 * 
 * 
 * var danmufu={
        obj:0,
        fu:function(){
            var url=GetQueryString("danmu");
            if(!url)return;
            if(danmufu.obj.url)return;
            danmufu.obj=new danmuf();
            danmufu.obj.url='https://comment.bilibili.com/'+url+'.xml';
            danmufu.obj.class='danmu';
            danmufu.obj.classs='danmus';
            danmufu.obj.speed=13;
            danmufu.obj.keyframe.fontsize=20;
            danmufu.obj.fu();
        }
    };danmufu.fu();

    需要的添加：
    视频暂停/播放:
    danmufu.obj.paus.fu();

    寻时：
    danmu.obj.goto.fu();

    video.ontimeupdate:
    danmufu.obj.timecheck.fu();

    

 */



/**
 * 自定义项
 */
var danmufStyle={
};







function danmuf(){

    /**
     * 赋予子对象以父对象
     */
    this.link();
}
danmuf.prototype={

    /**
     * 开关
     */
    on:1,

    /**
     * dom对象
     */
    dom:document.getElementsByTagName('video')[0],

    /**
     * default speed
     */
    speed:13,

    /**
     * class
     * 滚动
     * 固定
     */
    class:0,
    classs:0,

    /**
     * 弹幕文件地址
     */
    url:0,

    /**
     * 自定义项
     */
    style:danmufStyle,
    
    /**
     * 弹幕库
     */
    buff:0,

    /**
     * 当前渲染序号
     */
    mun:0,
    
    /**
     * 获取弹幕文件
     */
    getxml:{

        /**
         * 父对象
         */
        this_:0,

        /**
         * 主方法
         */
        fu:function(){
            var this_=this;
                xhr=new XMLHttpRequest();

            xhr.onreadystatechange=function(){
                if(this.readyState==4 && this.status == 200){
                    this_.this_.buff=this_.this_.relist(this_.this_.translate(this));
                    this_.this_.keyframe.setup();

                    //this_.this_.pushto.fu();
                }
            };

            xhr.open("GET",this.this_.url,true);
            xhr.send();
        }
    },

    /**
     * 读取弹幕缓存
     * 输入回应
     * 返回弹幕数组
     */
    translate:function(res){
        var kkk=res.responseXML.getElementsByTagName('d'),
            ppp=new Array();
        for(var a=0;a<kkk.length;a++){
            ppp[a]=new Array();
            ppp[a][0]=parseFloat(kkk[a].getAttribute('p').split(',')[0]);//time
            ppp[a][1]=kkk[a].innerHTML;
            ppp[a][2]=parseFloat(kkk[a].getAttribute('p').split(',')[2]);//fontsize
            ppp[a][3]=parseFloat(kkk[a].getAttribute('p').split(',')[1]);//location
            ppp[a][4]=parseFloat(kkk[a].getAttribute('p').split(',')[3]);//color
        }
        return ppp;
    },

    /**
     * 重排数组
     * 输入乱序数组
     * 输出按时间排列数组
     */
    relist:function(arr){
        /**
         * all：需要重构的数组
         */
        var all=new Array(),
            min=0;

        all.push(arr);

        /**
         * 输入参考点
         * 重构all数组（包含两部分 1.比参考点小 2.比参考点大）
         */
        function f(val){
            if(val.length==1){
                all.push(val);
                return val[0][0];
            }
            var less=new Array(),
                more=new Array();
            for(var a=1;a<val.length;a++){
                if(val[0][0]>val[a][0])less.push(val[a]);
                else more.push(val[a]);
            }
            less.push(val[0]);
            if(less.length!=0)all.push(less);
            if(more.length!=0)all.push(more);
            return val[0][0];
        }

        /**
         * 重排数组（初步处理后 all开头有些理应在结尾的元素）
         */
        for(var a=0;1;a++){
            if(all[0][0][0]<min&&arr.length==all.length)break;
            min=f(all.shift());
        }

        /**
         * all从双重数组变成单层
         */
        for(var a=0;a<all.length;a++){
            all.push(all.shift()[0]);
        }

        return all;
    },

    /**
     * 跳转
     */
    goto:{
        this_:0,

        fix:0,

        /**
         * 主方法
         */
        fu:function(){
            //if(this.this_.dom.paused)this.this_.paus.fu();

            var a;

            /**
             * 确定当前video时间对应的弹幕序号
             */
            for(a=0;1;a++){
                if(a==this.this_.buff.length-1)break;
                if(this.this_.buff[a][0]-this.this_.dom.currentTime>0)break;
            }
            this.fix=this.this_.buff[a][0]-this.this_.dom.currentTime;
            this.this_.mun=a;
            console.log(this.this_.mun+">"+this.this_.dom.paused)
            if(!this.this_.dom.paused)this.this_.pushto.fu();
            //if(this.this_.mun==this.this_.buff.length-1){
            //}
            

        }
    },

    /**
     * 控制弹幕位置
     */
    danmulist:{
        this_:0,
        
        /**
         * 弹幕轨道
         */
        li:new Array(),
        
        /**
         * 存储有关于是否回到顶部输出的数据
         */
        sign:0,

        /**
         * 确定弹幕轨道数量
         */
        setup:function(){
            this.sign=0;
            if(this.this_.mun!=0)return true;
            for(var a=0;a<14;a++)this.li.push(a);
        },

        /**
         * 主程序
         */
        relist:function(){
            if(this.this_.writediv.beginwritetime%3<this.sign&&this.this_.writediv.speed==this.this_.speed){
                this.li.sort();
            }
            //console.log(b.innerHTML+"?"+all.list.sign+"?"+begin%3)
            this.sign=this.this_.writediv.beginwritetime%3;
            var item=this.li.shift();
            this.li.push(item);
            return item;
        }


    },

    /**
     * 输出
     */
    writediv:{
        this_:0,
        
        /**
         * 该组的第一个输出对于的弹幕序号
         */
        beginwritemun:0,

        /**
         * 该组的每一个输出相对该组第一个的时间
         */
        beginwritetime:0,

        /**
         * 默认速度
         */
        speed:0,

        /**
         * 该组结束标志
         * =1
         */
        endwrite:0,

        /**
         * 主方法
         */
        fu:function(){
                var this_=this,
                    endwrite=this_.endwrite,
                    b=document.createElement('div');
                b.innerHTML=this.this_.buff[this.this_.mun][1];

                this.beginwritetime=this.this_.buff[this.this_.mun][0]-this.this_.buff[this.beginwritemun][0]+this.this_.goto.fix,
                this.speed=this.this_.speed;
                if(b.innerHTML.length>8)this.speed--;
                if(b.innerHTML.length>14)this.speed--;
                if(b.innerHTML.length>20)this.speed--;

                var listmun=this.this_.danmulist.relist();
                var colorr=parseInt(this.this_.buff[this.this_.mun][4]/65536),
                    colorg=parseInt(this.this_.buff[this.this_.mun][4]%65536/256),
                    colorb=parseInt(this.this_.buff[this.this_.mun][4]%256);

                if(this.this_.buff[this.this_.mun][3]<4){
                    b.setAttribute('class',this.this_.class);
                    b.setAttribute('style','animation:danmumu '+this.speed+'s linear '+this.beginwritetime+'s;\
                                    top:'+listmun*30+'px;\
                                    font-size:'+this.this_.buff[this.this_.mun][2]+'px;\
                                    color:rgb('+colorr+','+colorg+','+colorb+');');
    
                }else{

                    b.setAttribute('class',this.this_.classs);
                    b.setAttribute('style','animation:das 3s linear '+this.beginwritetime+'s;\
                                    font-size:'+this.this_.buff[this.this_.mun][2]+'px;\
                                    color:rgb('+colorr+','+colorg+','+colorb+');');
                }
                
                this.this_.dom.parentNode.children[0].appendChild(b);
                b.addEventListener("animationstart", function(){
                    //console.log(endwrite)
                    this.style.opacity=0.4;
                    if(endwrite)this_.this_.pushto.fu();
                });

                b.addEventListener("animationend", function(){
                    this.parentNode.removeChild(this);
                });
            },
    },

    /**
     * 从数组推出
     */
    pushto:{
        this_:0,

        /**
         * 主方法
         */
        fu:function(){
            if(!this.this_.on)return;

            if(this.this_.mun>=this.this_.buff.length-1){
                console.log('fi')
                return;
            }

            this.this_.writediv.endwrite=0;

            var cu=this.this_.mun?this.this_.mun-1:this.this_.mun;
            this.this_.writediv.beginwritemun=cu;
            for(;this.this_.mun<cu+7&&this.this_.mun<this.this_.buff.length-2;this.this_.mun++){
                this.this_.writediv.fu();
            }

            this.this_.writediv.endwrite=1;
            this.this_.writediv.fu();

            this.this_.mun++;
        },
    },

    /**
     * 暂停
     */
    paus:{
        this_:0,

        /**
         * 主方法
         */
        fu:function(){
            var this_=this;
            if(!this.this_.dom.paused){
                setTimeout(function(){
                    var dom=document.getElementsByClassName(this_.this_.class);
                    for(var a=0;a<dom.length;a++){
                        dom[a].style.animationPlayState="running";
                    }
                    dom=document.getElementsByClassName(this_.this_.classs);
                    for(var a=0;a<dom.length;a++){
                        dom[a].style.animationPlayState="running";
                    }
                },0);
                this.this_.goto.fu();
            }else{
                setTimeout(function(){
                    var dom=document.getElementsByClassName(this_.this_.class);
                    for(var a=0;a<dom.length;a++){
                        dom[a].style.animationPlayState="paused";
                    }
                    dom=document.getElementsByClassName(this_.this_.classs);
                    for(var a=0;a<dom.length;a++){
                        dom[a].style.animationPlayState="paused";
                    }
                },0);
            }
        }
    },

    /**
     * 时间校准
     */
    timecheck:{
        this_:0,

        /**
         * 校准间隔
         */
        val:0,

        fix:0,

        /**
         * 主方法
         */
        fu:function(){
            if(this.this_.mun>=this.this_.buff.length-1)return;
            var this_=this;
                this.val++;
                if(this.val>10){
                    this.val=0;
                    function fii(){
                        if(this_.this_.mun==0)return;
                        var a=this_.this_.buff[this_.this_.mun+1][0]>this_.this_.dom.currentTime;
                        var b=this_.this_.buff[this_.this_.mun-1][0]<this_.this_.dom.currentTime;
                        if(a&&b){
                            this_.fix=0;
                            return;
                        }
                        if(!a){
                            if(this_.fix<0)this_.fix=0
                            this_.fix++
                        }
                        if(!b){
                            if(this_.fix>0)this_.fix=0
                            this_.fix--
                        }
                        this_.this_.mun+=this_.fix;
                        fii();
                    }fii();
            }
        },
    
    },

    /**
     * 动画规定
     */
    keyframe:{
        this_:0,

        /**
         * css dom
         */
        dom:0,

        /**
         * default font size
         */
        fontsize:20,

        /**
         * setup
         */
        setup:function(){
            var this_=this,
                style=document.createElement('style');

            document.getElementsByTagName('head')[0].appendChild(style);

            this.dom=document.styleSheets[document.styleSheets.length-1];
            var maxl=0;
            for(var a=0;a<this.this_.buff.length;a++){
                if(maxl<this.this_.buff[a][1].length)maxl=this.this_.buff[a][1].length;
            }
            maxl=maxl*this.fontsize;

            this.dom.insertRule('@keyframes danmumu{0%{left:110%;}100%{left:-'+maxl+'px;}}',this.dom.rules.length);
            this.dom.insertRule('@keyframes das{0%{opacity:0.4}}',this.dom.rules.length);

       }
    },

    /**
     * 标签页切换
     */
    changepage:{
        this_:0,
        
        /**
         * main function
         */
        fu:function(){
            this.this_.goto.fu();
        },

        /**
         * setup
         */
        setup:function(){
            var this_=this;
            document.addEventListener("visibilitychange", function() {
                if(!document.hidden)this_.fu();
              });
        }
    },

    /**
     * 功能开关
     */
    onfu:function(){
        if(this.on)this.on=0;
        else {
            this.on=1;
            if(!this.dom.paused)this.pushto.fu();
        }
    },

    /**
     * 父this
     */
    link:function(){
        this.danmulist.this_=this;
        this.writediv.this_=this;
        this.pushto.this_=this;
        this.getxml.this_=this;
        this.goto.this_=this;
        this.paus.this_=this;
        this.timecheck.this_=this;
        this.keyframe.this_=this;
        this.changepage.this_=this;
    },
    
    /**
     * 入口
     */
    fu:function(){
        if(!this.on)return;

        this.getxml.fu();
        this.changepage.setup();
        this.danmulist.setup();

        return true;
    }
};
